
#ifndef _ROUTER_H
#define _ROUTER_H

#include "IPList.h"
#include <map>
#include <set>
#include <list>



/**
	 * This cass represents a router with its interfaces and neighbours router
	 * It is also a graph with its main algorithms
	 */
class Router
{
	friend std::ostream& operator <<(std::ostream& stream, const Router& Obj);

	public : 

		std::set<Router *> ngbr_router;		/* Neighbourhood router */
		IPList ngbr_interfaces;				/* Neighbourhood interface */
		IPList interfaces;					/* Router interfaces */

		/**
		 * Constructor.
		 * 
		 * Initialize ngbr_router_iterator
		 */
		Router ();

		/**
		 * This function add an IP address to the router
		 * which is an interface of this router
		 * 
		 * @param addr_ip the IP address
		 */
		void add_interface ( const std::string& addr_ip );	

		/**
		 * This function add a neighbourhood interface of this router
		 * 
		 * @param addr_ip the IP address if the neighbourhood interface
		 */
		void add_ngbr_interface ( const std::string& addr_ip );

		/**
		 * This function complete the ngrb_router vector using the interface map
		 * */
		void complete_router_neighbourhood();
 		
		/**
		 * This map make the relation between an interface and its associate
	 	 * router. 
 		 */
		static std::map<std::string, Router *> interface_map;

		/**
		 * This map contains all the chosen paths between this router and the 
		 * other router of the graph
		 */
		std::map<Router *, std::list<Router *>> chosen_paths;


		class RouterPath : public std::list<Router *>
		{
			public :
				std::string print_path();
			
				void push_back (Router * router);
				void pop_back();

			private :
	
				std::set<Router *> path_set;
			
		};

		/**
		 * This function returns all the possible paths from this router to 
		 * to the destination router. A path is a list of router.
		 * It uses the function is_redundant to not save the redundant path 
		 * and then useless for solving the constraint system.
		 * It also uses the nbgr_router_iterator ( see below ) for mark 
		 * router already seen and save their "discovery state"
		 * Every time this function is called the iterator ngbr_router_iterator
		 * needs to be re-initialized
		 * 
		 * @see Readfile.cpp
		 * 
 		 * @param destination the destination router
		 * 
		 * @return a list of all the discovered path
		 */
		std::list<RouterPath> get_all_paths ( Router * destination );

		/**
		 * This iterator is for the get_all_paths function.
		 * It's the nbgr_router set iterator.
		 * It allows to know if an neighbour router has already been treated or 
		 * not.
		 * It need to be re-initialize everytime function get_all_paths is 
		 * called
		 * 
		 * @see Readfile.cpp
		 */
		std::set<Router *>::iterator ngbr_router_iterator;
}; 




#endif /* _ROUTER_H */
